//
//  SISSFileUploadManager.m
//  SISSAPP
//
//  Created by 优房网 on 2017/5/31.
//  Copyright © 2017年 优房网. All rights reserved.
//

#import "SISSFileUploadManager.h"

@implementation SISSFileUploadManager


+ (instancetype)sharedManager {
    
    static SISSFileUploadManager *instance;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
        
    });
    
    return instance;
}

// 上传单个文件,不带文字信息
- (void)uploadFileWithURLStr:(NSString *)URLStr serverName:(NSString *)serverName filePath:(NSString *)filePath
{
    
    [self uploadFilesWithURLStr:URLStr serverName:serverName filePaths:@[filePath] textDict:nil success:nil failed:nil];
}

/*
 * 多文件上传的地址
 * 服务器接收文件的字段名,由服务器提供,千万不要修改
 * 要上传的文件路径集合,集合里面有几个路径,就表示上传几张图片
 * 文件上传时的文字信息
 */
- (void)uploadFilesWithURLStr:(NSString *)URLStr serverName:(NSString *)serverName filePaths:(NSArray*)filePaths textDict:(NSDictionary *)textDict success:(void (^)(id))successBlock failed:(void (^)(NSError *))failedBlock {
    // 1.URL
    NSURL *baseURL = [NSURL URLWithString:BASE_URL];
    if ([[baseURL path] length] > 0 && ![[baseURL absoluteString] hasSuffix:@"/"]) {
        baseURL = [baseURL URLByAppendingPathComponent:@""];
    }
    
    NSURL *URL = [NSURL URLWithString:URLStr relativeToURL:baseURL];
    // 2.可变请求
    NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:URL];
    requestM.timeoutInterval = 12; // 超时时长
    // 2.1 设置请求方法为POST
    requestM.HTTPMethod = @"POST";
    // 2.2 设置请求头里面的Content-Type
//    NSString *boundary = @"wfWiEWrgEFA9A78512weF7106A";
//    requestM.allHTTPHeaderFields = @{
//                                     @"Content-Type":[NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]
//                                     };
    [requestM setValue:@"multipart/form-data; boundary=youfangwangsissapp" forHTTPHeaderField:@"Content-Type"];
    [requestM setValue:[NSString stringWithFormat:@"%@ %@",[SISSUserAccount shared].token_type,[SISSUserAccount shared].access_token] forHTTPHeaderField:@"Authorization"];
    // 2.3 获取请求体二进制信息
    NSData *fromData = [self getFromDataWithServerName:serverName filePaths:filePaths textDict:textDict];
    // 添加加载菊花
    [SISSPublicSingleton shared].isHud = YES;
    if (![SISSPublicSingleton shared].isHud) {
        [MBProgressHUD YYR_ShowHUD:YES];
        [SISSPublicSingleton shared].isHud = YES;
    }

    // 3.获取单例session,发起上传任务,启动上传任务
    [[[NSURLSession sharedSession] uploadTaskWithRequest:requestM fromData:fromData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [SISSPublicSingleton shared].isHud = NO;
            [MBProgressHUD YYR_HideHUD:YES];
        }];
        // 4.处理响应
        if (error == nil && data != nil) {
            // 5.反序列化
            id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
            if (successBlock) {
                successBlock(result);
            }
            NSLog(@"%@",result);
        } else {
            if (failedBlock) {
                failedBlock(error);
            }
            NSLog(@"%@",error);
        }
        
    }] resume];
}

// 获取请求体的主方法
- (NSData *)getFromDataWithServerName:(NSString *)serverName filePaths:(NSArray*)filePaths textDict:(NSDictionary *)textDict {
    
    // 用于拼接整个请求体二进制信息
    NSMutableData *dataM = [NSMutableData data];
    
    // 拼接图片的二进制信息
    [filePaths enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        // 用于拼接1-4行的字符串的容器
        NSMutableString *stringM = [NSMutableString string];
        // 拼接文件开始的分隔符
        [stringM appendString:@"--youfangwangsissapp\r\n"];
        // 拼接表单数据 : obj 就是遍历出来的文件的本地路径
        [stringM appendFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n",serverName,[obj lastPathComponent]];
        // 拼接文件类型 : application/octet-stream 不指定文件类型,可以传多种类型
        [stringM appendString:@"Content-Type: application/octet-stream\r\n"];
        // 拼接单纯换行
        [stringM appendString:@"\r\n"];
        // 把1-4行的字符串拼接到dataM
        [dataM appendData:[stringM dataUsingEncoding:NSUTF8StringEncoding]];
        
        // 拼接文件的二进制信息
        [dataM appendData:[NSData dataWithContentsOfFile:obj]];
        
        // 拼接结尾
        [dataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }];
    
    // 拼接文字信息 key : status ; obj : 信息
    [textDict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        // 用于拼接字符串的请求体的容器
        NSMutableString *stringM = [NSMutableString string];
        // 拼接文字开始的分隔符
        [stringM appendString:@"--youfangwangsissapp\r\n"];
        // 拼接表单数据
        [stringM appendFormat:@"Content-Disposition: form-data; name=%@\r\n",key];
        // 拼接单纯的换行
        [stringM appendString:@"\r\n"];
        // 拼接文字信息
        [stringM appendFormat:@"%@\r\n",obj];
        // 把文字信息拼接进dataM
        [dataM appendData:[stringM dataUsingEncoding:NSUTF8StringEncoding]];
    }];
    
    // 拼接整个文件结束的分隔符
    [dataM appendData:[@"--youfangwangsissapp--\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
    return dataM.copy;
}

/*
 * 多文件上传的地址
 * 服务器接收文件的字段名,由服务器提供,千万不要修改
 * 要上传的文件路径集合,集合里面有几个路径,就表示上传几张图片
 * 文件上传时的文字信息
 */
- (void)uploadFilesWithURLStr:(NSString *)URLStr serverNames:(NSArray<NSString *> *)serverNames filePathsArr:(NSArray<NSArray *> *)filePathsArr textDict:(NSDictionary *)textDict success:(void (^)(id))successBlock failed:(void (^)(NSError *))failedBlock {
    // 1.URL
    NSURL *baseURL = [NSURL URLWithString:BASE_URL];
    if ([[baseURL path] length] > 0 && ![[baseURL absoluteString] hasSuffix:@"/"]) {
        baseURL = [baseURL URLByAppendingPathComponent:@""];
    }
    
    NSURL *URL = [NSURL URLWithString:URLStr relativeToURL:baseURL];
    // 2.可变请求
    NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:URL];
    requestM.timeoutInterval = 12; // 超时时长
    // 2.1 设置请求方法为POST
    requestM.HTTPMethod = @"POST";
    // 2.2 设置请求头里面的Content-Type
    //    NSString *boundary = @"wfWiEWrgEFA9A78512weF7106A";
    //    requestM.allHTTPHeaderFields = @{
    //                                     @"Content-Type":[NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]
    //                                     };
    [requestM setValue:@"multipart/form-data; boundary=youfangwangsissapp" forHTTPHeaderField:@"Content-Type"];
    [requestM setValue:[NSString stringWithFormat:@"%@ %@",[SISSUserAccount shared].token_type,[SISSUserAccount shared].access_token] forHTTPHeaderField:@"Authorization"];
    // 2.3 获取请求体二进制信息
    NSData *fromData = [self getFromDataWithServerNames:serverNames filePathsArr:filePathsArr textDict:textDict];
    // 添加加载菊花
    [SISSPublicSingleton shared].isHud = YES;
    if (![SISSPublicSingleton shared].isHud) {
        [MBProgressHUD YYR_ShowHUD:YES];
        [SISSPublicSingleton shared].isHud = YES;
    }
    
    // 3.获取单例session,发起上传任务,启动上传任务
    
    [[[NSURLSession sharedSession] uploadTaskWithRequest:requestM fromData:fromData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [SISSPublicSingleton shared].isHud = NO;
            [MBProgressHUD YYR_HideHUD:YES];
        }];
        // 4.处理响应
        if (error == nil && data != nil) {
            // 5.反序列化
            id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
            if (successBlock) {
                successBlock(result);
            }
            NSLog(@"%@",result);
        } else {
            if (failedBlock) {
                failedBlock(error);
            }
            NSLog(@"%@",error);
        }
    }] resume];
}

// 获取请求体的主方法
- (NSData *)getFromDataWithServerNames:(NSArray<NSString *> *)serverNames filePathsArr:(NSArray<NSArray *> *)filePathsArr textDict:(NSDictionary *)textDict {
    
    // 用于拼接整个请求体二进制信息
    NSMutableData *dataM = [NSMutableData data];
    
    [filePathsArr enumerateObjectsUsingBlock:^(NSArray * _Nonnull filePaths, NSUInteger serverIndex, BOOL * _Nonnull stop) {
        
        // 拼接图片的二进制信息
        [filePaths enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            // 用于拼接1-4行的字符串的容器
            NSMutableString *stringM = [NSMutableString string];
            // 拼接文件开始的分隔符
            [stringM appendString:@"--youfangwangsissapp\r\n"];
            // 拼接表单数据 : obj 就是遍历出来的文件的本地路径
            [stringM appendFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n",serverNames[serverIndex],[obj lastPathComponent]];
            // 拼接文件类型 : application/octet-stream 不指定文件类型,可以传多种类型
            [stringM appendString:@"Content-Type: application/octet-stream\r\n"];
            // 拼接单纯换行
            [stringM appendString:@"\r\n"];
            // 把1-4行的字符串拼接到dataM
            [dataM appendData:[stringM dataUsingEncoding:NSUTF8StringEncoding]];
            
            // 拼接文件的二进制信息
            [dataM appendData:[NSData dataWithContentsOfFile:obj]];
            
            // 拼接结尾
            [dataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        }];
    }];
    
    
    // 拼接文字信息 key : status ; obj : 信息
    [textDict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        // 用于拼接字符串的请求体的容器
        NSMutableString *stringM = [NSMutableString string];
        // 拼接文字开始的分隔符
        [stringM appendString:@"--youfangwangsissapp\r\n"];
        // 拼接表单数据
        [stringM appendFormat:@"Content-Disposition: form-data; name=%@\r\n",key];
        // 拼接单纯的换行
        [stringM appendString:@"\r\n"];
        // 拼接文字信息
        [stringM appendFormat:@"%@\r\n",obj];
        // 把文字信息拼接进dataM
        [dataM appendData:[stringM dataUsingEncoding:NSUTF8StringEncoding]];
    }];
    
    // 拼接整个文件结束的分隔符
    [dataM appendData:[@"--youfangwangsissapp--\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
    return dataM.copy;
}



@end
